import { BadRequestException, Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository, FindManyOptions, UpdateResult, In } from 'typeorm';
import { format } from 'date-fns';
import { CreateSurveyDto } from './dto/create-survey.dto';
import { Survey } from './entities/survey.entity';
import { UpdateSurveyDto } from './dto/update-survey.dto';
import { PaginationQueryDto } from 'src/common/dto/pagination-query.dto';
import { PaginationService } from 'src/common/service/pagination.service';
import { DelFlag } from 'src/common/enums/del-flag.enum';
import { SurveyQueryDto } from './dto/query-survey.dto';
import { PaginationResult } from 'src/common/interfaces/pagination-results.interface';
import { Question } from '../question/entities/question.entity';
import { Result } from '../result/entities/result.entity';
import { SurveyExtend } from './interfact/extend';

@Injectable()
export class SurveyService {
  constructor(
    @InjectRepository(Survey)
    private readonly surveyRepository: Repository<Survey>,
    private paginationService: PaginationService,
    @InjectRepository(Question)
    private readonly questionRepository: Repository<Question>,
    @InjectRepository(Result)
    private readonly resultRepository: Repository<Result>,
  ) { }
  private async validateIds(questionIds: string, resultIds: string): Promise<{ questions: Question[], results: Result[] }> {
    const questionIdArray = questionIds.split(',')
    const resultIdArray = resultIds.split(',')

    const questions = await this.questionRepository.findByIds(questionIdArray);
    const results = await this.resultRepository.findByIds(resultIdArray);

    if (questions.length !== questionIdArray.length) {
      throw new BadRequestException('Some questions do not exist');
    }

    if (results.length !== resultIdArray.length) {
      throw new BadRequestException('Some results do not exist');
    }

    return { questions, results };
  }
  async create(createSurveyDto: CreateSurveyDto): Promise<Survey> {
    const { questionIds, resultIds } = createSurveyDto;
    await this.validateIds(questionIds, resultIds);

    const survey = this.surveyRepository.create(createSurveyDto);
    return this.surveyRepository.save(survey);
  }

  async findAll(surveyQueryDto: SurveyQueryDto): Promise<PaginationResult<Survey | SurveyExtend>> {
    const {
      // result,
      limit, page } = surveyQueryDto;
    const where: any = {
      del_flag: DelFlag.ACTIVE,
      // id: '6923aa02-b57f-4dc3-b12d-a68493c2af3f'
    };

    // if (result) {
    //   where.result = Like(`%${result}%`);
    // }

    // return this.paginationService.paginate(this.surveyRepository, { limit, where, page });
    const paginationResult = await this.paginationService.paginate(
      this.surveyRepository,
      { limit, page, where }
    );
    const allQuestionIds = paginationResult.items.map(survey => survey.questionIds.split(',')).flat();
    const allResultIds = paginationResult.items.map(survey => survey.resultIds.split(',')).flat();
    const questions = await this.questionRepository.find({ where: { id: In(allQuestionIds) } });
    const results = await this.resultRepository.find({ where: { id: In(allResultIds) } });

    const formattedData = paginationResult.items.map(survey => {
      const surveyQuestions = questions.filter(question => survey.questionIds.split(',').includes(question.id.toString()));
      return {
        ...survey,
        questionNames: surveyQuestions.map(question => question.question).join(', '),
        resultsNames:  results.map(result => result.keyword).join(', '),
      };
    });
    return {
      ...paginationResult,
      items: formattedData,
    };
  }
  async findOne(id: string): Promise<Survey> {
    const survey = await this.surveyRepository.findOne({ where: { id, del_flag: DelFlag.ACTIVE } });

    if (!survey) {
      throw new NotFoundException(`Survey with ID ${id} not found`);
    }
    return survey;
  }

  async update(id: string, updateSurveyDto: UpdateSurveyDto): Promise<Survey> {
    const { questionIds, resultIds } = updateSurveyDto;
    await this.validateIds(questionIds, resultIds);

    // const survey = await this.surveyRepository.preload({
    //   id, // 确保实体的 ID 字段存在
    //   ...updateSurveyDto
    // });

    // if (!survey) {
    //   throw new NotFoundException(`Survey with ID ${id} not found`);
    // }
    await this.surveyRepository.update(id, updateSurveyDto);
    const updatedSurvey = await this.surveyRepository.findOne({ where: { id, del_flag: DelFlag.ACTIVE } });
    if (!updatedSurvey) {
      throw new NotFoundException(`Survey with ID ${id} not found`);
    }
    return updatedSurvey;
  }

  async remove(id: string): Promise<UpdateResult> {
    return await this.surveyRepository.update(id, { del_flag: DelFlag.DELETED });

  }
  async delete(id: string): Promise<void> {
    await this.surveyRepository.delete(id);
  }

}
